// middleware/jwt.go
package middleware

import (
	"errors"
	"time"

	"github.com/dgrijalva/jwt-go"
	"go.uber.org/zap"
)

// TokenClaims 定义JWT令牌的声明结构
type TokenClaims struct {
	UserID uint `json:"user_id"`
	RoleID uint `json:"role_id"`
	jwt.StandardClaims
}

// GenerateToken 生成JWT令牌
func GenerateToken(userID uint, roleID uint, secretKey string, expiresIn time.Duration) (string, error) {
	// 创建令牌声明
	claims := &TokenClaims{
		UserID: userID,
		RoleID: roleID,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: time.Now().Add(expiresIn).Unix(),
			IssuedAt:  time.Now().Unix(),
			Issuer:    "your-app-name", // 替换为你的应用名称
		},
	}

	// 创建令牌对象
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// 生成签名的令牌
	tokenString, err := token.SignedString([]byte(secretKey))
	if err != nil {
		zap.L().Error("生成JWT令牌失败", zap.Error(err))
		return "", err
	}

	return tokenString, nil
}

// ParseToken 解析JWT令牌
func ParseToken(tokenString string, secretKey string) (*TokenClaims, error) {
	// 解析令牌
	token, err := jwt.ParseWithClaims(tokenString, &TokenClaims{}, func(token *jwt.Token) (interface{}, error) {
		// 验证签名方法
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, errors.New("无效的签名方法")
		}
		return []byte(secretKey), nil
	})

	if err != nil {
		zap.L().Error("解析JWT令牌失败", zap.Error(err))
		return nil, err
	}

	// 验证令牌并获取声明
	if claims, ok := token.Claims.(*TokenClaims); ok && token.Valid {
		return claims, nil
	}

	return nil, errors.New("无效的令牌")
}
